﻿Imports Microsoft.Office.Interop.Excel
Imports System.Text.RegularExpressions
Public Class MatchParser
    Private xl As Application
    Private Ws As Worksheet
    Private mWs As Worksheet
    Private type As String
    Public succ As List(Of SuccObject)
    Public succ_fromcodes As List(Of SuccObject)
    Public err As List(Of String)
    Private srccount As Integer
    Private matchcount As Integer
    Private match As Object
    Private match_sitecode As Object
    Private match_model As Object
    Private match_price As Object
    Private src As Object
    Private src_price As Object
    Private src_avail As Object
    Private src_model As Object

    Private rowsToDelete As Integer
    Private siteColumn As Integer
    Private vendorColumn As Integer
    Private modelColumn As Integer
    Private matchPriceColumn As Integer

    Private delim As String

    Public dict As Dictionary(Of String, String)
    Public matchset As HashSet(Of String)
    Private matchdict As Dictionary(Of String, Double)
    Function translate(s As String) As String
        Dim t As String
        t = Regex.Replace(s, "[^\w/\\]", "")
        translate = t.ToLower
    End Function
    Sub New(ByRef xl As Application, ByRef Ws As Worksheet, ByRef mWs As Worksheet, type As String)
        succ = New List(Of SuccObject)
        succ_fromcodes = New List(Of SuccObject)
        err = New List(Of String)
        Me.Ws = Ws
        Me.mWs = mWs
        Me.type = type
        Me.xl = xl
        dict = New Dictionary(Of String, String)
        matchset = New HashSet(Of String)
        matchdict = New Dictionary(Of String, Double)
    End Sub
    Function process() As List(Of SuccObject)
        Dim i As Integer

        delim = err_csv_delim
        Select Case type
            Case "Олег"
                vendorColumn = 2
                siteColumn = 7
                rowsToDelete = 1
                modelColumn = 2
                matchPriceColumn = 6
            Case "Вася"
                vendorColumn = 1
                siteColumn = 2
                rowsToDelete = 1
                modelColumn = 1
                matchPriceColumn = 3 ' fake
            Case "Диски_Покрышкино"
                vendorColumn = 4
                siteColumn = 1
                rowsToDelete = 1
                modelColumn = 2
                matchPriceColumn = 3
            Case "Белшинторг"
                vendorColumn = 3
                siteColumn = 1
                modelColumn = 2
                rowsToDelete = 1
                matchPriceColumn = 4 'fake
            Case Else
                vendorColumn = 8
                siteColumn = 2
                rowsToDelete = 3
                modelColumn = 3
                matchPriceColumn = 4
        End Select
        Try
            initGeneric(vendorColumn, siteColumn, rowsToDelete, modelColumn, matchPriceColumn, Regex.IsMatch(type, "^Диски"))
        Catch x As Exception
            MsgBox("Прайс " + type + " не удалось обработать по кодам, возможно в прайсе не осталось строк после разбора")
            process = Nothing
            Exit Function
        End Try

        generateMatch()



        Dim avail(UBound(src)) As Boolean
        Dim codes(UBound(src)) As String
        For i = 1 To UBound(src)
            If src_model(i, 1) Is Nothing Then
                src_model(i, 1) = ""
            End If
            Dim s As String = translate(src(i, 1))
            If (matchset.Contains(s)) Then
                codes(i - 1) = dict.Item(s)
                matchdict.Remove(s)

                avail(i - 1) = productAvailable(src_avail(i, 1))
                Dim price As Double = getPrice(src_price(i, 1)) ' * Double.Parse(BYR_USD_CONV, 0)
                Dim quantity As String = getQuantity(src_avail(i, 1))
                'If quantity = "" Then
                '    err.Add(type + delim + (i + rowsToDelete).ToString + delim _
                '            + "количество=" + quantity + ", недопустимо" + delim _
                '            + src_model(i, 1).ToString + delim + s)
                '    'codes(i-1).dict.Item(s)
                '    Continue For
                'End If
                Dim so As New SuccObject(dict.Item(s), avail(i - 1), price, quantity, type)
                'codes(i - 1) = so.code
                succ.Add(so)
            Else
                err.Add(type + delim + (i + rowsToDelete).ToString + delim + "нет совпадений" + ":" + s + ", оригинал: " + src(i, 1).ToString + delim + src_model(i, 1).ToString)
                codes(i - 1) = sitecode_null
            End If
        Next

        'succ_fromcodes.AddRange(succ)

        For Each d As KeyValuePair(Of String, Double) In matchdict
            Dim td As Double
            If d.Value = -1 Then
                td = 1
            Else
                td = d.Value
            End If
            'dict.Item(d.Key) change
            succ_fromcodes.Add(New SuccObject(dict.Item(d.Key), False, td, SUCCOBJECT_FROMCODES, type))
        Next

        ExcelOps.getColumn(Ws, RESULT_SITECODE_COLUMN, UBound(src)).Value = xl.WorksheetFunction.Transpose(codes)
        ExcelOps.getColumn(Ws, RESULT_AVAIL_COLUMN, UBound(src)).Value = xl.WorksheetFunction.Transpose(avail)

        process = succ

    End Function
    Private Sub generateMatch()
        Dim i As Integer
        For i = 1 To UBound(match)
            If match_model(i, 1) Is Nothing Then
                match_model(i, 1) = ""
            End If

            If Not match_sitecode(i, 1) Is Nothing Then
                If Not match(i, 1) Is Nothing Then
                    Dim m As String = translate(match(i, 1).ToString)

                    If Not dict.ContainsKey(m) Then
                        If match_sitecode(i, 1).ToString <> "не найден" Then
                            matchset.Add(m)
                            matchdict.Add(m, getPrice(match_price(i, 1))) '* Double.Parse(BYR_USD_CONV, 0))
                            dict.Add(m, match_sitecode(i, 1))
                        End If
                    Else 'dict.ContainsKey(match(i, 1))
                        err.Add(type + delim + (i + rowsToDelete).ToString + delim + "дубликат кода поставщика " + m + " original: " + match(i, 1).ToString + delim + match_model(i, 1).ToString)
                    End If
                Else ' match(i,1) is nothing
                    Dim price As Double = getPrice(match_price(i, 1)) ' * Double.Parse(BYR_USD_CONV, 0)
                    Dim so As New SuccObject(match_sitecode(i, 1), avail:=False, price:=price, quantity:=0, type:=type)
                    succ.Add(so)
                    'err.Add(type + delim + (i + rowsToDelete).ToString + delim + "отсутствует код поставщика" + delim + match_model(i, 1).ToString)
                End If
            Else 'match_sitecode(i, 1) Is Nothing
                err.Add(type + delim + (i + rowsToDelete).ToString + delim + "отсутствует код сайта" + delim + match_model(i, 1).ToString)
            End If
        Next
    End Sub
    Private Function productAvailable(o As Object) As Boolean
        If (Not o Is Nothing) Then
            If o.ToString <> "" And o.ToString <> "0" Then
                productAvailable = True
            Else
                productAvailable = False
            End If
        Else
            productAvailable = False
        End If
    End Function
    Shared Function getPrice(o As Object) As Double
        If TypeOf o Is Double Then
            getPrice = o
        Else
            getPrice = -1
        End If
    End Function
    Private Sub initGeneric(Optional vendor_col As Integer = 8, _
                            Optional sitecode_col As Integer = 2, _
                            Optional rowsdel As Integer = 3, _
                            Optional model_col As Integer = 3, _
                            Optional matchprice_col As Integer = 4, _
                            Optional discs As Boolean = False)
        mWs.Rows("1:" + rowsdel.ToString).Delete(Shift:=XlDeleteShiftDirection.xlShiftUp)
        'matchcount = mWs.Cells(1, vendor_col).CurrentRegion.Rows.Count
        matchcount = mWs.Cells(1, sitecode_col).CurrentRegion.Rows.Count

        match = ExcelOps.getColumn(mWs, vendor_col, matchcount).Value
        match_sitecode = ExcelOps.getColumn(mWs, sitecode_col, matchcount).Value
        match_model = ExcelOps.getColumn(mWs, model_col, matchcount).Value
        match_price = ExcelOps.getColumn(mWs, matchprice_col, matchcount).Value

        srccount = Ws.Cells(1, 1).CurrentRegion.Rows.Count
        If srccount = 1 And Ws.Cells(1, 1).value Is Nothing Then

        End If
        src = ExcelOps.getColumn(Ws, 1, srccount).Value

        'need calc val
        'src_price = ExcelOps.getColumn(Ws, 10, srccount).Value
        If discs Then
            src_price = ExcelOps.getColumn(Ws, 13, srccount).Value
            src_avail = ExcelOps.getColumn(Ws, 10, srccount).Value
            src_model = ExcelOps.getColumn(Ws, 3, srccount).Value
        Else
            src_price = ExcelOps.getColumn(Ws, 11, srccount).Value
            src_avail = ExcelOps.getColumn(Ws, 9, srccount).Value
            src_model = ExcelOps.getColumn(Ws, 3, srccount).Value
        End If

    End Sub

    Shared Function getQuantity(quantity As Object) As String
        If (quantity Is Nothing) Then 'Если поле с количеством пустое, то оно должно отражаться в файле для сайта,
            getQuantity = ""
            Exit Function

        End If
        'If TypeOf quantity Is Double Then
        '    If (quantity = 1 Or quantity = 0) Then 'Если количество товара 1 или 0, то эти товары не должны попасть в файл для сайта.
        '        getQuantity = ""
        '    Else
        '        getQuantity = quantity.ToString
        '    End If
        '    Exit Function
        'End If

        If (LCase(Trim(quantity.ToString)) = "заказ") Then 'если написано "заказ", то это =0
            getQuantity = "0"
        Else
            getQuantity = quantity.ToString
        End If
    End Function

End Class
